package com.uziot.bucket.guava.lock;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author shidt
 * @version V1.0
 * @className GuavaGroupLock
 * @date 2020-04-23 23:54:26
 * @description
 */
@Slf4j
public class GuavaGroupLock {
    /**
     * 分组缓存锁
     */
    private static final Map<String, Cache<String, Integer>> GROUP_CACHE_MAP = new ConcurrentHashMap<>(16);

    /**
     * 通道查询限制缓存
     *
     * @param groupId 分组号
     * @param key     k
     */
    public void putLock(String groupId, String key) {
        // 缓存有效期从数据库配置
        Cache<String, Integer> channelCache = GROUP_CACHE_MAP.get(groupId);
        if (null == channelCache) {
            log.info("创建当前分组锁ID：{}", groupId);
            // TODO 可根据分组号，限制时间，进行数据库配置
            Cache<String, Integer> cache = CacheBuilder.newBuilder().expireAfterWrite(5L, TimeUnit.MINUTES).build();
            cache.put(key, 0);
            GROUP_CACHE_MAP.put(groupId, cache);
        } else {
            channelCache.put(key, 0);
        }
        log.info("当前分组ID：{}，已锁定的KEY键：{}", groupId, key);
    }

    /**
     * 获取通过KEY查询是否锁定
     *
     * @param groupId 通道号
     * @param key     key
     * @return v
     */
    public boolean checkLock(String groupId, String key) {
        Cache<String, Integer> cache = GROUP_CACHE_MAP.get(groupId);
        if (null == cache) {
            return false;
        } else {
            Integer present = cache.getIfPresent(key);
            if (null == present) {
                log.info("当前分组ID：{}，未锁定的KEY键：{}", groupId, key);
                return false;
            } else {
                log.info("当前分组ID：{}，锁定中的KEY键：{}", groupId, key);
                return true;
            }
        }
    }

    /**
     * 释放锁定
     *
     * @param groupId channelId
     * @param key     key
     */
    public void resetLock(String groupId, String key) {
        // 缓存有效期从数据库配置
        Cache<String, Integer> cache = GROUP_CACHE_MAP.get(groupId);
        if (null != cache) {
            cache.invalidate(key);
            log.info("当前分组ID：{}，释放锁的KEY键：{}", groupId, key);
        }
    }

    /**
     * 清除当前分组的锁
     */
    public void resetLock(String groupId) {
        // 缓存有效期从数据库配置
        Cache<String, Integer> cache = GROUP_CACHE_MAP.get(groupId);
        if (null != cache) {
            cache.invalidateAll();
            log.info("当前分组ID：{}，释放所有锁定的键", groupId);
        }
    }

    /**
     * 清除所有锁
     */
    public void resetLockAll() {
        // 缓存有效期从数据库配置
        GROUP_CACHE_MAP.forEach((k, v) -> {
            v.invalidateAll();
        });
        log.info("已释放所有锁定的键，合计释放分组锁数量：{}", GROUP_CACHE_MAP.size());
    }
}
